﻿/**
 * @file std_deque.c
 * Copyright (c) 2019 Gaaagaa. All rights reserved.
 * 
 * @author  : Gaaagaa
 * @date    : 2019-09-09
 * @version : 1.0.0.0
 * @brief   : 使用 C API 的接口形式实现 双端队列 容器。
 */

/**
 * The MIT License (MIT)
 * Copyright (c) Gaaagaa. All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "std_deque.h"
#include "std_debug.h"

#include "std_deque.inl"

////////////////////////////////////////////////////////////////////////////////

#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif // __GNUC__

////////////////////////////////////////////////////////////////////////////////

//====================================================================

// 
// xstd_deque_t 的内部操作接口
// 

/**********************************************************/
/**
 * @brief 计算 xstd_deque_t 对象节点元素合适的 分块大小。
 * @note  xstd_deque_t 对象必须已经指定了 所存储元素对象的缓存大小。
 */
static inline xdeq_size_t deque_calc_chksize(xdeq_this_t xdeq_this)
{
#if 1
    if (XDEQ_ESIZE(xdeq_this) <= (1 << 4))
    {
        return ((xdeq_size_t)(1) << 
            ((xdeq_size_t)(5) - std_ceil2pn(XDEQ_ESIZE(xdeq_this))));
    }
#else
    if (XDEQ_ESIZE(xdeq_this) <= 1)
        return 32;
    else if (XDEQ_ESIZE(xdeq_this) <= 2)
        return 16;
    else if (XDEQ_ESIZE(xdeq_this) <= 4)
        return 8;
    else if (XDEQ_ESIZE(xdeq_this) <= 8)
        return 4;
    else if (XDEQ_ESIZE(xdeq_this) <= 16)
        return 2;
#endif
    return 1;
}

/**********************************************************/
/**
 * @brief 计算 xstd_deque_t 对象最大可存储的 节点数量。
 * @note  xstd_deque_t 对象必须已经确定了 分块大小。
 */
static inline xdeq_size_t deque_calc_maxsize(xdeq_this_t xdeq_this)
{
    xdeq_size_t xmap_size = std_floor2pow(
        ((xdeq_size_t)~0) / XDEQ_CHUNK_MSIZE(xdeq_this));
    XASSERT(xmap_size <= XDEQ_MAX_MAPSIZE(xdeq_this));

    return (xmap_size * xdeq_this->xchk_size);
}

/**********************************************************/
/**
 * @brief 
 * 判断区间 [ xdeq_bpos, xdeq_epos ] 是否局限于
 * 区间 [ XDEQ_BEGIN(xdeq_this), XDEQ_END(xdeq_this) ] 内。
 */
static inline xdeq_bool_t deque_opos_inscope(
                                xdeq_this_t xdeq_this,
                                xdeq_opos_t xdeq_bpos,
                                xdeq_opos_t xdeq_epos)
{
    if (xdeq_bpos < xdeq_this->xmap_bpos) xdeq_bpos += xdeq_this->xmap_maxv + 1;
    if (xdeq_epos < xdeq_this->xmap_bpos) xdeq_epos += xdeq_this->xmap_maxv + 1;
    return ((xdeq_bpos >= xdeq_this->xmap_bpos) && (xdeq_bpos <= xdeq_epos) &&
            (xdeq_epos <= (xdeq_this->xmap_bpos + xdeq_this->xdeq_size)));
}

/**********************************************************/
/**
 * @brief 
 * 判断 xdeq_iter 迭代器是否位于
 * 区间 [ XDEQ_BEGIN(xdeq_this), XDEQ_END(xdeq_this) ) 内。
 */
static inline xdeq_bool_t deque_iter_ref(
                                xdeq_this_t xdeq_this,
                                xdeq_iter_t xdeq_iter)
{
    return (XDEQ_ITER_CAST(xdeq_opos_t, xdeq_iter) < XDEQ_END(xdeq_this));
}

/**********************************************************/
/**
 * @brief 
 * 判断 xdeq_iter 迭代器是否位于
 * 区间 [ XDEQ_BEGIN(xdeq_this), XDEQ_END(xdeq_this) ] 内。
 */
static inline xdeq_bool_t deque_iter_valid(
                                xdeq_this_t xdeq_this,
                                xdeq_iter_t xdeq_iter)
{
    return (XDEQ_ITER_CAST(xdeq_opos_t, xdeq_iter) <= XDEQ_END(xdeq_this));
}

/**********************************************************/
/**
 * @brief 
 * 判断区间 [ xdeq_iter, xdeq_rter ] 是否局限于
 * 区间 [ XDEQ_BEGIN(xdeq_this), XDEQ_END(xdeq_this) ] 内。
 */
static inline xdeq_bool_t deque_iter_inscope(
                                xdeq_this_t xdeq_this,
                                xdeq_iter_t xdeq_lter,
                                xdeq_iter_t xdeq_rter)
{
    return ((XDEQ_ITER_CAST(xdeq_opos_t, xdeq_lter) <= 
             XDEQ_ITER_CAST(xdeq_opos_t, xdeq_rter)) &&
            (XDEQ_ITER_CAST(xdeq_opos_t, xdeq_rter) <= 
             XDEQ_END(xdeq_this)));
}

/**********************************************************/
/**
 * @brief 使用 xdeq_elem 值，覆盖非空区间 [ xdeq_bpos, xdeq_epos ) 。
 */
static xdeq_void_t deque_range_conver(
                        xdeq_this_t xdeq_this,
                        xdeq_elem_t xdeq_elem,
                        xdeq_opos_t xdeq_bpos,
                        xdeq_opos_t xdeq_epos)
{
    xdeq_cpos_t xdst_cpos = 0;
    xdeq_npos_t xdst_npos = 0;
    xdeq_elem_t xdst_elem = XDEQ_NULL;

    if (xdeq_bpos != xdeq_epos)
    {
        xdst_cpos = XDEQ_CPOS(xdeq_this, xdeq_bpos);
        xdst_npos = XDEQ_NPOS(xdeq_this, xdeq_bpos);

        do
        {
            xdst_elem = XDEQ_NPTR(xdeq_this, xdst_cpos, xdst_npos);
            XDEQ_ALDEST(xdeq_this, xdst_elem);
            XDEQ_ALFROM(xdeq_this, xdst_elem, xdeq_elem);

            XDEQ_CNP_NEXT(xdeq_this, xdst_cpos, xdst_npos);
        } while (++xdeq_bpos != xdeq_epos);
    }
}

/**********************************************************/
/**
 * @brief 使用 xdeq_elem 值，填充空区间 [ xdeq_bpos, xdeq_epos ) 。
 */
static xdeq_void_t deque_range_fill(
                        xdeq_this_t xdeq_this,
                        xdeq_elem_t xdeq_elem,
                        xdeq_opos_t xdeq_bpos,
                        xdeq_opos_t xdeq_epos)
{
    xdeq_cpos_t xdst_cpos = 0;
    xdeq_npos_t xdst_npos = 0;

    if (xdeq_bpos != xdeq_epos)
    {
        xdst_cpos = XDEQ_CPOS(xdeq_this, xdeq_bpos);
        xdst_npos = XDEQ_NPOS(xdeq_this, xdeq_bpos);

        do
        {
            XDEQ_ALFROM(
                xdeq_this,
                XDEQ_NPTR(xdeq_this, xdst_cpos, xdst_npos),
                xdeq_elem);
            XDEQ_CNP_NEXT(xdeq_this, xdst_cpos, xdst_npos);
        } while (++xdeq_bpos != xdeq_epos);
    }
}

/**********************************************************/
/**
 * @brief 删除区间 [ xdeq_bpos, xdeq_epos ) 内的元素。
 */
static xdeq_void_t deque_range_erase(
                        xdeq_this_t xdeq_this,
                        xdeq_opos_t xdeq_bpos,
                        xdeq_opos_t xdeq_epos)
{
    xdeq_cpos_t xdst_cpos = 0;
    xdeq_npos_t xdst_npos = 0;

    if (xdeq_bpos != xdeq_epos)
    {
        xdst_cpos = XDEQ_CPOS(xdeq_this, xdeq_bpos);
        xdst_npos = XDEQ_NPOS(xdeq_this, xdeq_bpos);

        do
        {
            XDEQ_ALDEST(xdeq_this, XDEQ_NPTR(xdeq_this, xdst_cpos, xdst_npos));
            XDEQ_CNP_NEXT(xdeq_this, xdst_cpos, xdst_npos);
        } while (++xdeq_bpos != xdeq_epos);
    }
}

/**********************************************************/
/**
 * @brief 申请 分块 缓存。
 */
static inline xdeq_cptr_t deque_cptr_alloc(
                                xdeq_this_t xdeq_this)
{
    xdeq_cptr_t xdeq_cptr = xdeq_this->xchk_rptr;
    if (XDEQ_NULL == xdeq_cptr)
        xdeq_cptr = (xdeq_cptr_t)
            XDEQ_MALLOC(xdeq_this, XDEQ_CHUNK_MSIZE(xdeq_this));
    else
        xdeq_this->xchk_rptr = XDEQ_NULL;
    return xdeq_cptr;
}

/**********************************************************/
/**
 * @brief 回收 分块 缓存。
 */
static inline xdeq_void_t deque_cptr_recyc(
                                xdeq_this_t xdeq_this,
                                xdeq_cptr_t xdeq_cptr)
{
    if (XDEQ_NULL != xdeq_this->xchk_rptr)
        XDEQ_DEALLOC(xdeq_this, xdeq_this->xchk_rptr);
    xdeq_this->xchk_rptr = xdeq_cptr;
}

/**********************************************************/
/**
 * @brief 
 * 将区间 [ xmap_bptr, xmap_eptr ) 内的 分块指针值，
 * 复制到 [ xmap_dptr, ... ) 上。
 * 
 * @param [in ] xmap_bptr : 所复制的区间起始位置。
 * @param [in ] xmap_eptr : 所复制的区间结束位置。
 * @param [out] xmap_dptr : 复制操作的目标区间起始位置。
 * 
 * @return xdeq_pptr_t : 返回 [ xdeq_dptr, ... ) 区间的结束位置。
 */
static inline xdeq_pptr_t deque_pptr_copy(
                            xdeq_pptr_t xmap_bptr,
                            xdeq_pptr_t xmap_eptr,
                            xdeq_pptr_t xmap_dptr)
{
    XASSERT(xmap_bptr <= xmap_eptr);

    while (xmap_bptr != xmap_eptr)
        *xmap_dptr++ = *xmap_bptr++;
    return xmap_dptr;
}

/**********************************************************/
/**
 * @brief 
 * 将区间 [ xmap_pptr, xmap_pptr + xdeq_size ) 内的
 * 分块指针值置空。
 * 
 * @param [in ] xmap_pptr : 所复制的区间起始位置。
 * @param [in ] xdeq_size : 所复制的区间大小。
 */
static inline xdeq_void_t deque_pptr_clear(
                            xdeq_pptr_t xmap_pptr,
                            xdeq_size_t xdeq_size)
{
    for (; xdeq_size > 0; --xdeq_size)
        *xmap_pptr++ = XDEQ_NULL;
}

/**********************************************************/
/**
 * @brief 
 * 对 xstd_deque_t 对象 分块映射数组 的 
 * 区间 [ xmap_bptr, xmap_eptr )，释放其内的 各个分块缓存。
 * 
 * @param [in ] xdeq_this : xstd_deque_t 对象。
 * @param [in ] xmap_bptr : 所操作区间的起始位置。
 * @param [in ] xmap_eptr : 所操作区间的结束位置。
 */
static inline xdeq_void_t deque_pptr_erase(
                            xdeq_this_t xdeq_this,
                            xdeq_pptr_t xmap_bptr,
                            xdeq_pptr_t xmap_eptr)
{
    XASSERT(xmap_bptr <= xmap_eptr);

    for (; xmap_bptr != xmap_eptr; ++xmap_bptr)
    {
        deque_cptr_recyc(xdeq_this, *xmap_bptr);
        *xmap_bptr = XDEQ_NULL;
    }
}

/**********************************************************/
/**
 * @brief 
 * 对 xstd_deque_t 对象 分块映射数组 的 
 * 区间 [ xmap_bptr, xmap_eptr )，填充其内的 各个分块缓存。
 * 
 * @param [in ] xdeq_this : xstd_deque_t 对象。
 * @param [in ] xmap_bptr : 所操作区间的起始位置。
 * @param [in ] xmap_eptr : 所操作区间的结束位置。
 */
static inline xdeq_void_t deque_pptr_fill(
                                xdeq_this_t xdeq_this,
                                xdeq_pptr_t xmap_bptr,
                                xdeq_pptr_t xmap_eptr)
{
    XASSERT(xmap_bptr <= xmap_eptr);

    for (; xmap_bptr != xmap_eptr; ++xmap_bptr)
    {
        XASSERT(XDEQ_NULL == *xmap_bptr);
        *xmap_bptr = deque_cptr_alloc(xdeq_this);
    }
}

/**********************************************************/
/**
 * @brief 
 * 将区间 [ xmap_bptr, xmap_eptr ) 内的 分块指针值，
 * 向左移动至 [ xmap_dptr, ... )。
 * 
 * @param [in ] xmap_dptr : 目标区间起始位置。
 * @param [in ] xmap_bptr : 所移动区间的起始位置。
 * @param [in ] xmap_eptr : 所移动区间的结束位置。
 */
static inline xdeq_void_t deque_pptr_lmove(
                            xdeq_pptr_t xmap_dptr,
                            xdeq_pptr_t xmap_bptr,
                            xdeq_pptr_t xmap_eptr)
{
    XASSERT(xmap_bptr <= xmap_eptr);

    if (xmap_dptr < xmap_bptr)
    {
        for (; xmap_bptr != xmap_eptr; )
        {
            XASSERT(XDEQ_NULL == *xmap_dptr);
            XASSERT(XDEQ_NULL != *xmap_bptr);
            *xmap_dptr++ = *xmap_bptr;
            *xmap_bptr++ = XDEQ_NULL;
        }
    }
}

/**********************************************************/
/**
 * @brief 
 * 将区间 [ xmap_bptr, xmap_eptr ) 内的 分块指针值，
 * 向右移动至 [ xmap_dptr, ... )。
 * 
 * @param [in ] xmap_dptr : 目标区间起始位置。
 * @param [in ] xmap_bptr : 所移动区间的起始位置。
 * @param [in ] xmap_eptr : 所移动区间的结束位置。
 */
static inline xdeq_void_t deque_pptr_rmove(
                            xdeq_pptr_t xmap_dptr,
                            xdeq_pptr_t xmap_bptr,
                            xdeq_pptr_t xmap_eptr)
{
    XASSERT(xmap_bptr <= xmap_eptr);

    if (xmap_dptr > xmap_bptr)
    {
        xmap_dptr += (xmap_eptr - xmap_bptr);
        for (; xmap_bptr != xmap_eptr; )
        {
            --xmap_dptr;
            --xmap_eptr;
            XASSERT(XDEQ_NULL == *xmap_dptr);
            XASSERT(XDEQ_NULL != *xmap_eptr);
            *xmap_dptr = *xmap_eptr;
            *xmap_eptr = XDEQ_NULL;
        }
    }
}

/**********************************************************/
/**
 * @brief 
 * 对区间 [ xdeq_bpos, xdeq_epos ) 所覆盖区域上的各个分块节点，
 * 都铺上 分块缓存，确保不为空。
 */
static inline xdeq_void_t deque_chunk_rollout(
                                xdeq_this_t xdeq_this,
                                xdeq_cpos_t xchk_bpos,
                                xdeq_cpos_t xchk_epos)
{
    if (xchk_bpos > xchk_epos)
    {
        for (; xchk_bpos < xdeq_this->xmap_size; ++xchk_bpos)
        {
            XASSERT(XDEQ_NULL == XDEQ_CPTR(xdeq_this, xchk_bpos));
            XDEQ_CPTR(xdeq_this, xchk_bpos) = deque_cptr_alloc(xdeq_this);
        }

        xchk_bpos = 0;
    }

    for (; xchk_bpos < xchk_epos; ++xchk_bpos)
    {
        XASSERT(XDEQ_NULL == XDEQ_CPTR(xdeq_this, xchk_bpos));
        XDEQ_CPTR(xdeq_this, xchk_bpos) = deque_cptr_alloc(xdeq_this);
    }
}

/**********************************************************/
/**
 * @brief 
 * 对区间 ( xdeq_bpos, xdeq_epos ] 所覆盖区域上的各个分块节点，
 * 都铺上 分块缓存，确保不为空。
 */
static inline xdeq_void_t deque_chunk_rollout_r(
                                xdeq_this_t xdeq_this,
                                xdeq_cpos_t xchk_bpos,
                                xdeq_cpos_t xchk_epos)
{
    if (xchk_epos < xchk_bpos)
    {
        for (; xchk_epos != ((xdeq_cpos_t)-1); --xchk_epos)
        {
            XASSERT(XDEQ_NULL == XDEQ_CPTR(xdeq_this, xchk_epos));
            XDEQ_CPTR(xdeq_this, xchk_epos) = deque_cptr_alloc(xdeq_this);
        }

        xchk_epos = xdeq_this->xmap_size - 1;
    }

    for (; xchk_epos > xchk_bpos; --xchk_epos)
    {
        XASSERT(XDEQ_NULL == XDEQ_CPTR(xdeq_this, xchk_epos));
        XDEQ_CPTR(xdeq_this, xchk_epos) = deque_cptr_alloc(xdeq_this);
    }
}

/**********************************************************/
/**
 * @brief 
 * 对区间 [ xdeq_bpos, xdeq_epos ) 所覆盖区域上的各个分块节点，
 * 回收 分块缓存，释放闲置资源。
 */
static inline xdeq_void_t deque_chunk_rollup(
                                xdeq_this_t xdeq_this,
                                xdeq_cpos_t xchk_bpos,
                                xdeq_cpos_t xchk_epos)
{
    if (xchk_bpos > xchk_epos)
    {
        for (; xchk_bpos < xdeq_this->xmap_size; ++xchk_bpos)
        {
            XASSERT(XDEQ_NULL != XDEQ_CPTR(xdeq_this, xchk_bpos));
            deque_cptr_recyc(xdeq_this, XDEQ_CPTR(xdeq_this, xchk_bpos));
            XDEQ_CPTR(xdeq_this, xchk_bpos) = XDEQ_NULL;
        }

        xchk_bpos = 0;
    }

    for (; xchk_bpos < xchk_epos; ++xchk_bpos)
    {
        XASSERT(XDEQ_NULL != XDEQ_CPTR(xdeq_this, xchk_bpos));
        deque_cptr_recyc(xdeq_this, XDEQ_CPTR(xdeq_this, xchk_bpos));
        XDEQ_CPTR(xdeq_this, xchk_bpos) = XDEQ_NULL;
    }
}

/**********************************************************/
/**
 * @brief 
 * 对区间 ( xdeq_bpos, xdeq_epos ] 所覆盖区域上的各个分块节点，
 * 回收 分块缓存，释放闲置资源。
 */
static inline xdeq_void_t deque_chunk_rollup_r(
                                xdeq_this_t xdeq_this,
                                xdeq_cpos_t xchk_bpos,
                                xdeq_cpos_t xchk_epos)
{
    if (xchk_epos < xchk_bpos)
    {
        for (; xchk_epos != ((xdeq_cpos_t)-1); --xchk_epos)
        {
            XASSERT(XDEQ_NULL != XDEQ_CPTR(xdeq_this, xchk_epos));
            deque_cptr_recyc(xdeq_this, XDEQ_CPTR(xdeq_this, xchk_epos));
            XDEQ_CPTR(xdeq_this, xchk_epos) = XDEQ_NULL;
        }

        xchk_epos = xdeq_this->xmap_size - 1;
    }

    for (; xchk_epos > xchk_bpos; --xchk_epos)
    {
        XASSERT(XDEQ_NULL != XDEQ_CPTR(xdeq_this, xchk_epos));
        deque_cptr_recyc(xdeq_this, XDEQ_CPTR(xdeq_this, xchk_epos));
        XDEQ_CPTR(xdeq_this, xchk_epos) = XDEQ_NULL;
    }
}

/**********************************************************/
/**
 * @brief 
 * 将元素节点区间 [ XDEQ_BEGIN(xdeq_this), xdeq_opos ) 
 * 向首端左移 xdeq_size 个节点。
 * @note 
 * 该接口用于腾出区间 [ xdeq_opos, xdeq_opos + xdeq_size ) ，
 * 为后续 插入新的元素节点 做准备。
 * 
 * @param [in ] xdeq_this : xstd_deque_t 对象。
 * @param [in ] xdeq_opos : 所移区间的结束位置。
 * @param [in ] xdeq_size : 移动的跨度大小。
 * 
 * @return xdeq_opos_t : 返回 xdeq_opos + xdeq_size 对应的位置。
 */
static xdeq_opos_t deque_head_lshift(
                        xdeq_this_t xdeq_this,
                        xdeq_opos_t xdeq_opos,
                        xdeq_size_t xdeq_size)
{
    xdeq_opos_t xdeq_bpos = XDEQ_BEGIN(xdeq_this);
    xdeq_cpos_t xsrc_cpos = XDEQ_CPOS(xdeq_this, xdeq_bpos);
    xdeq_npos_t xsrc_npos = 0;

    xdeq_cpos_t xdst_cpos = XDEQ_CPOS(xdeq_this, xdeq_bpos - xdeq_size);
    xdeq_npos_t xdst_npos = 0;

    if ((0 == XDEQ_NPOS(xdeq_this, xdeq_opos)) &&
        (0 == XDEQ_NPOS(xdeq_this, xdeq_opos + xdeq_size)))
    {
        for (; xdeq_bpos < xdeq_opos; xdeq_bpos += xdeq_this->xchk_size)
        {
            XASSERT(XDEQ_NULL != XDEQ_CPTR(xdeq_this, xsrc_cpos));
            XASSERT(XDEQ_NULL == XDEQ_CPTR(xdeq_this, xdst_cpos));
            XDEQ_CPTR(xdeq_this, xdst_cpos) = XDEQ_CPTR(xdeq_this, xsrc_cpos);
            XDEQ_CPTR(xdeq_this, xsrc_cpos) = XDEQ_NULL;

            if (++xdst_cpos == xdeq_this->xmap_size)
                xdst_cpos = 0;
            if (++xsrc_cpos == xdeq_this->xmap_size)
                xsrc_cpos = 0;
        }

        deque_chunk_rollout(xdeq_this, xdst_cpos, xsrc_cpos);
    }
    else
    {
        deque_chunk_rollout(xdeq_this, xdst_cpos, xsrc_cpos);

        xsrc_npos = XDEQ_NPOS(xdeq_this, xdeq_bpos);
        xdst_npos = XDEQ_NPOS(xdeq_this, xdeq_bpos - xdeq_size);
        for (; xdeq_bpos != xdeq_opos; ++xdeq_bpos)
        {
            XDEQ_ALMOVE(
                xdeq_this,
                XDEQ_NPTR(xdeq_this, xdst_cpos, xdst_npos),
                XDEQ_NPTR(xdeq_this, xsrc_cpos, xsrc_npos));

            XDEQ_CNP_NEXT(xdeq_this, xsrc_cpos, xsrc_npos);
            XDEQ_CNP_NEXT(xdeq_this, xdst_cpos, xdst_npos);
        }
    }

    xdeq_this->xmap_bpos  = XDEQ_VPOS(xdeq_this, XDEQ_BEGIN(xdeq_this) - xdeq_size);
    xdeq_this->xdeq_size += xdeq_size;

    return (xdeq_opos + xdeq_size);
}

/**********************************************************/
/**
 * @brief 
 * 将区间 [ XDEQ_BEGIN(xdeq_this), xdeq_opos ) 
 * 从首端右移 xdeq_size 个节点。
 * @note 
 * 在删除区间 [ xdeq_opos, xdeq_opos + xdeq_size ) 内的元素节点后，
 * 可调用该接口，用剩余的首部节点覆盖这一空白区域。
 * 
 * @param [in ] xdeq_this : xstd_deque_t 对象。
 * @param [in ] xdeq_opos : 所移区间的结束位置。
 * @param [in ] xdeq_size : 移动的跨度大小。
 * 
 * @return xdeq_opos_t : 返回 xdeq_opos 对应的位置。
 */
static xdeq_opos_t deque_head_rshift(
                        xdeq_this_t xdeq_this,
                        xdeq_opos_t xdeq_opos,
                        xdeq_size_t xdeq_size)
{
    xdeq_opos_t xdeq_bpos = xdeq_opos;
    xdeq_cpos_t xsrc_cpos = XDEQ_CPOS(xdeq_this, xdeq_bpos);
    xdeq_npos_t xsrc_npos = 0;

    xdeq_cpos_t xdst_cpos = XDEQ_CPOS(xdeq_this, xdeq_bpos + xdeq_size);
    xdeq_npos_t xdst_npos = 0;

    if ((0 == XDEQ_NPOS(xdeq_this, xdeq_opos)) &&
        (0 == XDEQ_NPOS(xdeq_this, xdeq_opos + xdeq_size)))
    {
        deque_chunk_rollup(xdeq_this, xsrc_cpos, xdst_cpos);

        for (; xdeq_bpos >= xdeq_this->xchk_size; xdeq_bpos -= xdeq_this->xchk_size)
        {
            if (0 == xsrc_cpos--)
                xsrc_cpos = xdeq_this->xmap_size - 1;
            if (0 == xdst_cpos--)
                xdst_cpos = xdeq_this->xmap_size - 1;

            XASSERT(XDEQ_NULL != XDEQ_CPTR(xdeq_this, xsrc_cpos));
            XASSERT(XDEQ_NULL == XDEQ_CPTR(xdeq_this, xdst_cpos));
            XDEQ_CPTR(xdeq_this, xdst_cpos) = XDEQ_CPTR(xdeq_this, xsrc_cpos);
            XDEQ_CPTR(xdeq_this, xsrc_cpos) = XDEQ_NULL;
        }
    }
    else
    {
        xsrc_npos = XDEQ_NPOS(xdeq_this, xdeq_bpos);
        xdst_npos = XDEQ_NPOS(xdeq_this, xdeq_bpos + xdeq_size);
        for (; xdeq_bpos != XDEQ_REND(xdeq_this); --xdeq_bpos)
        {
            XDEQ_CNP_PREV(xdeq_this, xsrc_cpos, xsrc_npos);
            XDEQ_CNP_PREV(xdeq_this, xdst_cpos, xdst_npos);

            XDEQ_ALMOVE(
                xdeq_this,
                XDEQ_NPTR(xdeq_this, xdst_cpos, xdst_npos),
                XDEQ_NPTR(xdeq_this, xsrc_cpos, xsrc_npos));
        }

        deque_chunk_rollup(xdeq_this, xsrc_cpos, xdst_cpos);
    }

    xdeq_this->xmap_bpos  = XDEQ_VPOS(xdeq_this, XDEQ_BEGIN(xdeq_this) + xdeq_size);
    xdeq_this->xdeq_size -= xdeq_size;

    return xdeq_opos;
}

/**********************************************************/
/**
 * @brief 
 * 将区间 [ xdeq_opos, XDEQ_END(xdeq_this) ) 
 * 从尾端左移 xdeq_size 个节点。
 * @note 
 * 在删除区间 [ xdeq_opos - xdeq_size, xdeq_opos ) 内的元素节点后，
 * 可调用该接口，用剩余的尾部节点覆盖这一空白区域。
 * 
 * @param [in ] xdeq_this : xstd_deque_t 对象。
 * @param [in ] xdeq_opos : 所移区间的起始位置。
 * @param [in ] xdeq_size : 移动的跨度大小。
 * 
 * @return xdeq_opos_t : 返回 xdeq_opos 对应的位置。
 */
static xdeq_opos_t deque_tail_lshift(
                        xdeq_this_t xdeq_this,
                        xdeq_opos_t xdeq_opos,
                        xdeq_size_t xdeq_size)
{
    xdeq_opos_t xdeq_bpos = xdeq_opos - 1;
    xdeq_cpos_t xsrc_cpos = XDEQ_CPOS(xdeq_this, xdeq_bpos);
    xdeq_npos_t xsrc_npos = 0;

    xdeq_cpos_t xdst_cpos = XDEQ_CPOS(xdeq_this, xdeq_bpos - xdeq_size);
    xdeq_npos_t xdst_npos = 0;

    if ((0 == XDEQ_NPOS(xdeq_this, xdeq_opos)) &&
        (0 == XDEQ_NPOS(xdeq_this, xdeq_opos - xdeq_size)))
    {
        deque_chunk_rollup_r(xdeq_this, xdst_cpos, xsrc_cpos);

        for (; xdeq_bpos < XDEQ_RBEGIN(xdeq_this); xdeq_bpos += xdeq_this->xchk_size)
        {
            if (++xsrc_cpos == xdeq_this->xmap_size)
                xsrc_cpos = 0;
            if (++xdst_cpos == xdeq_this->xmap_size)
                xdst_cpos = 0;

            XASSERT(XDEQ_NULL != XDEQ_CPTR(xdeq_this, xsrc_cpos));
            XASSERT(XDEQ_NULL == XDEQ_CPTR(xdeq_this, xdst_cpos));
            XDEQ_CPTR(xdeq_this, xdst_cpos) = XDEQ_CPTR(xdeq_this, xsrc_cpos);
            XDEQ_CPTR(xdeq_this, xsrc_cpos) = XDEQ_NULL;
        }
    }
    else
    {
        xsrc_npos = XDEQ_NPOS(xdeq_this, xdeq_bpos);
        xdst_npos = XDEQ_NPOS(xdeq_this, xdeq_bpos - xdeq_size);
        for (; xdeq_bpos != XDEQ_RBEGIN(xdeq_this); ++xdeq_bpos)
        {
            XDEQ_CNP_NEXT(xdeq_this, xsrc_cpos, xsrc_npos);
            XDEQ_CNP_NEXT(xdeq_this, xdst_cpos, xdst_npos);

            XDEQ_ALMOVE(
                xdeq_this,
                XDEQ_NPTR(xdeq_this, xdst_cpos, xdst_npos),
                XDEQ_NPTR(xdeq_this, xsrc_cpos, xsrc_npos));
        }

        deque_chunk_rollup_r(xdeq_this, xdst_cpos, xsrc_cpos);
    }

    xdeq_this->xdeq_size -= xdeq_size;

    return xdeq_opos;
}

/**********************************************************/
/**
 * @brief 
 * 将区间 [ xdeq_opos, XDEQ_END(xdeq_this) ) 
 * 向尾端右移 xdeq_size 个节点。
 * @note 
 * 该接口用于腾出区间 [ xdeq_opos, xdeq_opos + xdeq_size ) ，
 * 为后续 插入新的元素节点 做准备。
 * 
 * @param [in ] xdeq_this : xstd_deque_t 对象。
 * @param [in ] xdeq_opos : 所移区间的起始位置。
 * @param [in ] xdeq_size : 移动的跨度大小。
 * 
 * @return xdeq_opos_t : 返回 xdeq_opos + xdeq_size 对应的位置。
 */
static xdeq_opos_t deque_tail_rshift(
                        xdeq_this_t xdeq_this,
                        xdeq_opos_t xdeq_opos,
                        xdeq_size_t xdeq_size)
{
    xdeq_opos_t xdeq_bpos = XDEQ_RBEGIN(xdeq_this);
    xdeq_cpos_t xsrc_cpos = XDEQ_CPOS(xdeq_this, xdeq_bpos);
    xdeq_npos_t xsrc_npos = 0;

    xdeq_cpos_t xdst_cpos = XDEQ_CPOS(xdeq_this, xdeq_bpos + xdeq_size);
    xdeq_npos_t xdst_npos = 0;

    if ((0 == XDEQ_NPOS(xdeq_this, xdeq_opos)) &&
        (0 == XDEQ_NPOS(xdeq_this, xdeq_opos + xdeq_size)))
    {
        for (--xdeq_opos; xdeq_bpos > xdeq_opos; xdeq_bpos -= xdeq_this->xchk_size)
        {
            XASSERT(XDEQ_NULL != XDEQ_CPTR(xdeq_this, xsrc_cpos));
            XASSERT(XDEQ_NULL == XDEQ_CPTR(xdeq_this, xdst_cpos));
            XDEQ_CPTR(xdeq_this, xdst_cpos) = XDEQ_CPTR(xdeq_this, xsrc_cpos);
            XDEQ_CPTR(xdeq_this, xsrc_cpos) = XDEQ_NULL;

            if (0 == xsrc_cpos--)
                xsrc_cpos = xdeq_this->xmap_size - 1;
            if (0 == xdst_cpos--)
                xdst_cpos = xdeq_this->xmap_size - 1;
        }

        deque_chunk_rollout_r(xdeq_this, xsrc_cpos, xdst_cpos);
    }
    else
    {
        deque_chunk_rollout_r(xdeq_this, xsrc_cpos, xdst_cpos);

        xsrc_npos = XDEQ_NPOS(xdeq_this, xdeq_bpos);
        xdst_npos = XDEQ_NPOS(xdeq_this, xdeq_bpos + xdeq_size);
        for (--xdeq_opos; xdeq_bpos != xdeq_opos; --xdeq_bpos)
        {
            XDEQ_ALMOVE(
                xdeq_this,
                XDEQ_NPTR(xdeq_this, xdst_cpos, xdst_npos),
                XDEQ_NPTR(xdeq_this, xsrc_cpos, xsrc_npos));

            XDEQ_CNP_PREV(xdeq_this, xsrc_cpos, xsrc_npos);
            XDEQ_CNP_PREV(xdeq_this, xdst_cpos, xdst_npos);
        }
    }

    xdeq_this->xdeq_size += xdeq_size;

    return (xdeq_opos + xdeq_size + 1);
}

/**********************************************************/
/**
 * @brief 对 xstd_deque_t 对象的 分块映射数组 进行扩容操作。
 * 
 * @param [in,out] xdeq_this : xstd_deque_t 对象。
 * @param [in    ] xst_gsize : 扩容操作所增加的大小。
 */
static xdeq_void_t deque_map_expand(
                        xdeq_this_t xdeq_this,
                        xdeq_size_t xst_gsize)
{
    XASSERT(xst_gsize > 0);

    xdeq_size_t xmap_size = 0;
    xdeq_pptr_t xmap_pptr = XDEQ_NULL;
    xdeq_cpos_t xchk_cpos = 0;
    xdeq_pptr_t xmap_trav = XDEQ_NULL;

    //======================================
    // 计算出新的 分块映射数组 的容量，并分配其缓存

    xmap_size = (xdeq_this->xmap_size > 0) ? xdeq_this->xmap_size : 1;
    while (((xmap_size - xdeq_this->xmap_size) < xst_gsize) || 
           (xmap_size < XDEQ_MIN_MAPSIZE(xdeq_this)))
    {
        XASSERT(xmap_size <= (XDEQ_MAX_MAPSIZE(xdeq_this) - xmap_size));
        xmap_size <<= 1;
    }

    xmap_pptr = (xdeq_pptr_t)XDEQ_MALLOC(
                    xdeq_this, xmap_size * sizeof(xdeq_cptr_t));
    XASSERT(XDEQ_NULL != xmap_pptr);

    // 重新校正扩容操作所增加的大小
    xst_gsize = xmap_size - xdeq_this->xmap_size;

    //======================================
    // 复制原 分块映射数组 的内容至 新数组 中

    xchk_cpos = XDEQ_CPOS(xdeq_this, XDEQ_BEGIN(xdeq_this));
    xmap_trav = xmap_pptr + xchk_cpos;

    xmap_trav = deque_pptr_copy(
                    xdeq_this->xmap_pptr + xchk_cpos,
                    xdeq_this->xmap_pptr + xdeq_this->xmap_size,
                    xmap_trav);

    if (xchk_cpos <= xst_gsize)
    {
        xmap_trav = deque_pptr_copy(
                        xdeq_this->xmap_pptr,
                        xdeq_this->xmap_pptr + xchk_cpos,
                        xmap_trav);

        deque_pptr_clear(xmap_trav, xst_gsize - xchk_cpos);
        deque_pptr_clear(xmap_pptr, xchk_cpos);
    }
    else
    {
        deque_pptr_copy(
            xdeq_this->xmap_pptr,
            xdeq_this->xmap_pptr + xst_gsize,
            xmap_trav);

        xmap_trav = deque_pptr_copy(
                        xdeq_this->xmap_pptr + xst_gsize,
                        xdeq_this->xmap_pptr + xchk_cpos,
                        xmap_pptr);

        deque_pptr_clear(xmap_trav, xst_gsize);
    }

    //======================================
    // 更新 xstd_deque_t 对象的 分块映射数组 相关信息

    if (XDEQ_NULL != xdeq_this->xmap_pptr)
    {
        XDEQ_DEALLOC(xdeq_this, xdeq_this->xmap_pptr);
    }

    xdeq_this->xmap_pptr = xmap_pptr;
    xdeq_this->xmap_size = xmap_size;
    xdeq_this->xmap_maxv = xmap_size * xdeq_this->xchk_size - 1;

    //======================================
}

/**********************************************************/
/**
 * @brief 收缩 xstd_deque_t 对象的 分块映射数组缓存。
 */
static xdeq_void_t deque_map_reduce(xdeq_this_t xdeq_this)
{
    xdeq_cpos_t xmpos_head = 0;
    xdeq_cpos_t xmpos_tail = 0;

    xdeq_size_t xmap_nsize = 0;
    xdeq_pptr_t xmap_nvptr = XDEQ_NULL;

    do
    {
        //======================================

        if (0 == xdeq_this->xmap_size)
            break;
        XASSERT(XDEQ_NULL != xdeq_this->xmap_pptr);

        if (0 == xdeq_this->xdeq_size)
        {
            deque_pptr_erase(
                xdeq_this,
                xdeq_this->xmap_pptr,
                xdeq_this->xmap_pptr + xdeq_this->xmap_size);

            XDEQ_DEALLOC(xdeq_this, xdeq_this->xmap_pptr);

            xdeq_this->xmap_pptr = XDEQ_NULL;
            xdeq_this->xmap_size = 0;
            xdeq_this->xmap_maxv = 0;
            xdeq_this->xmap_bpos = 0;
            break;
        }

        //======================================
        // 清理掉未使用的 分块 缓存

        xmpos_head = XDEQ_CPOS(xdeq_this, XDEQ_BEGIN(xdeq_this));
        xmpos_tail = XDEQ_CPOS(xdeq_this, XDEQ_RBEGIN(xdeq_this));

        if (xmpos_head <= xmpos_tail)
        {
            deque_pptr_erase(
                xdeq_this,
                xdeq_this->xmap_pptr,
                xdeq_this->xmap_pptr + xmpos_head);

            deque_pptr_erase(
                xdeq_this,
                xdeq_this->xmap_pptr + xmpos_tail + 1,
                xdeq_this->xmap_pptr + xdeq_this->xmap_size);

            xmap_nsize = xmpos_tail - xmpos_head + 1;
        }
        else
        {
            deque_pptr_erase(
                xdeq_this,
                xdeq_this->xmap_pptr + xmpos_tail + 1,
                xdeq_this->xmap_pptr + xmpos_head);

            xmap_nsize = xdeq_this->xmap_size + xmpos_tail - xmpos_head + 1;
        }

        //======================================
        // 收缩 分块映射数组 的缓存

        // 若使用中的分块数量，仍达到半数，则取消 分块指针数组 的收缩操作
        if ((xmap_nsize > (xdeq_this->xmap_size / 2)) ||
            (xdeq_this->xmap_size <= XDEQ_MIN_MAPSIZE(xdeq_this)))
        {
            break;
        }

        xmap_nsize = std_ceil2pow(xmap_nsize);
        XASSERT(xmap_nsize <= XDEQ_MAX_MAPSIZE(xdeq_this));

        xmap_nvptr = (xdeq_pptr_t)XDEQ_MALLOC(xdeq_this, xmap_nsize * sizeof(xdeq_cptr_t));
        XASSERT(XDEQ_NULL != xmap_nvptr);

        if (xmpos_head <= xmpos_tail)
        {
            deque_pptr_copy(
                xdeq_this->xmap_pptr + xmpos_head,
                xdeq_this->xmap_pptr + xmpos_tail + 1,
                xmap_nvptr);
        }
        else
        {
            deque_pptr_copy(
                xdeq_this->xmap_pptr,
                xdeq_this->xmap_pptr + xmpos_tail + 1,
                deque_pptr_copy(
                    xdeq_this->xmap_pptr + xmpos_head,
                    xdeq_this->xmap_pptr + xdeq_this->xmap_size,
                    xmap_nvptr));
        }

        XDEQ_DEALLOC(xdeq_this, xdeq_this->xmap_pptr);

        xdeq_this->xmap_bpos = XDEQ_NPOS(xdeq_this, xdeq_this->xmap_bpos);
        xdeq_this->xmap_maxv = xmap_nsize * xdeq_this->xchk_size - 1;
        xdeq_this->xmap_size = xmap_nsize;
        xdeq_this->xmap_pptr = xmap_nvptr;

        //======================================
    } while (0);
}

//====================================================================

// 
// xstd_deque_t 的内嵌宏模块代码
// 

#define XDEQ_PUSH_BEGIN(xcheck_opos, xdeq_opos)                             \
    xdeq_cpos_t xmap_cpos = 0;                                              \
    xdeq_npos_t xmap_npos = 0;                                              \
                                                                            \
    do                                                                      \
    {                                                                       \
        if ((0 == XDEQ_NPOS(xdeq_this, (xcheck_opos))) &&                   \
            (xdeq_this->xmap_size == XDEQ_CHUNK_USED(xdeq_this)))           \
        {                                                                   \
            deque_map_expand(xdeq_this, 1);                                 \
        }                                                                   \
                                                                            \
        xmap_cpos = XDEQ_CPOS(xdeq_this, xdeq_opos);                        \
        xmap_npos = XDEQ_NPOS(xdeq_this, xdeq_opos);                        \
                                                                            \
        if (XDEQ_NULL == XDEQ_CPTR(xdeq_this, xmap_cpos))                   \
        {                                                                   \
            XDEQ_CPTR(xdeq_this, xmap_cpos) = deque_cptr_alloc(xdeq_this);  \
        }                                                                   \
    } while (0)

#define XDEQ_PUSH_TOELEM            \
    XDEQ_NPTR(xdeq_this, xmap_cpos, xmap_npos)

#define XDEQ_PUSH_ALFROM(xdeq_elem) \
    XDEQ_ALFROM(xdeq_this, XDEQ_PUSH_TOELEM, (xdeq_elem))

#define XDEQ_PUSH_ALMOVE(xdeq_elem) \
    XDEQ_ALFROM(xdeq_this, XDEQ_PUSH_TOELEM, (xdeq_elem))

#define XDEQ_PUSH_END               \
    do { ++xdeq_this->xdeq_size; } while (0)

//====================================================================

#define XDEQ_PUSH_FRONT_BEGIN \
    XDEQ_PUSH_BEGIN(XDEQ_BEGIN(xdeq_this), XDEQ_REND(xdeq_this))

#define XDEQ_PUSH_FRONT_END   \
    xdeq_this->xmap_bpos = XDEQ_VPOS(xdeq_this, XDEQ_BEGIN(xdeq_this) - 1); \
    XDEQ_PUSH_END

#define XDEQ_PUSH_BACK_BEGIN  \
    XDEQ_PUSH_BEGIN(XDEQ_END(xdeq_this), XDEQ_END(xdeq_this))

#define XDEQ_PUSH_BACK_END    \
    XDEQ_PUSH_END

//====================================================================

#define XDEQ_INSERT_BEGIN(xdeq_opos, xst_count)                                 \
    xdeq_opos_t xdeq_epos = (xdeq_opos);                                        \
    xdeq_size_t xchk_nums = 0;                                                  \
                                                                                \
    do                                                                          \
    {                                                                           \
        if ((xdeq_opos) <= (xdeq_this->xdeq_size / 2))                          \
        {                                                                       \
            xchk_nums = XDEQ_CHUNK_COUNT(                                       \
                            xdeq_this,                                          \
                            xdeq_this->xmap_bpos - (xst_count),                 \
                            xdeq_this->xdeq_size + (xst_count));                \
            if (xdeq_this->xmap_size < xchk_nums)                               \
            {                                                                   \
                deque_map_expand(xdeq_this, xchk_nums - xdeq_this->xmap_size);  \
            }                                                                   \
                                                                                \
            xdeq_epos = deque_head_lshift(xdeq_this, (xdeq_opos), (xst_count)); \
        }                                                                       \
        else                                                                    \
        {                                                                       \
            xchk_nums = XDEQ_CHUNK_COUNT(                                       \
                            xdeq_this,                                          \
                            xdeq_this->xmap_bpos,                               \
                            xdeq_this->xdeq_size + (xst_count));                \
            if (xdeq_this->xmap_size < xchk_nums)                               \
            {                                                                   \
                deque_map_expand(xdeq_this, xchk_nums - xdeq_this->xmap_size);  \
            }                                                                   \
                                                                                \
            xdeq_epos = deque_tail_rshift(xdeq_this, (xdeq_opos), (xst_count)); \
        }                                                                       \
    } while (0)

#define XDEQ_INSERT_ALFORM(xdeq_opos, xdeq_elem)    \
    XDEQ_ALFROM(xdeq_this, XDEQ_ELEM(xdeq_this, (xdeq_opos)), (xdeq_elem))

#define XDEQ_INSERT_ALMOVE(xdeq_opos, xdeq_elem)    \
    XDEQ_ALMOVE(xdeq_this, XDEQ_ELEM(xdeq_this, (xdeq_opos)), (xdeq_elem))

#define XDEQ_INSERT_FILL(xdeq_opos, xdeq_elem)      \
    deque_range_fill(xdeq_this, (xdeq_elem), (xdeq_opos), xdeq_epos)

#define XDEQ_INSERT_END(xdeq_opos)                  \
    XDEQ_ITER_CAST(xdeq_iter_t, (xdeq_opos))

//====================================================================

// 
// xstd_deque_t 的外部操作接口
// 

/**********************************************************/
/**
 * @brief 返回内部的 sizeof(xstd_deque_t) 值。
 */
xdeq_size_t std_deque_sizeof(void)
{
    return (xdeq_size_t)sizeof(xstd_deque_t);
}

/**********************************************************/
/**
 * @brief 创建 xstd_deque_t 对象。
 * @note  应使用 @see std_deque_destroy() 销毁所创建的对象。
 * 
 * @param [in ] xdeq_ctxt : 队列 所存储的节点元素上下文描述信息。
 * 
 * @return xdeq_this_t : 返回所创建的 xstd_deque_t 对象指针。
 */
xdeq_this_t std_deque_create(xdeq_ctxt_t xdeq_ctxt)
{
    XASSERT(XDEQ_NULL != xdeq_ctxt);
    XASSERT(0 != xdeq_ctxt->xstd_etype);
    XASSERT(0 != xdeq_ctxt->xstd_esize);

    xstd_altor_t xstd_altor = XSTD_ALTOR_NCREF(xdeq_ctxt->xstd_altor);
    xdeq_this_t xdeq_this =
        (xdeq_this_t)xstd_altor->xfunc_allocate(sizeof(xstd_deque_t));
    XASSERT(XDEQ_NULL != xdeq_this);

    return std_deque_emplace_create(xdeq_this, xdeq_ctxt);
}

/**********************************************************/
/**
 * @brief 
 * 销毁 xstd_deque_t 对象，
 * 其由 @see std_deque_create() 接口所创建。
 */
xdeq_void_t std_deque_destroy(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);

    xstd_altor_t xstd_altor = XDEQ_ALTOR(xdeq_this);

    std_deque_emplace_destroy(xdeq_this);
    xstd_altor->xfunc_dealloc(xdeq_this);
}

/**********************************************************/
/**
 * @brief 在指定的缓存上创建 xstd_deque_t 对象。
 * @note
 * 1. 所使用的缓存，其大小应不小于 @see std_deque_sizeof() 的返回值。
 * 2. 销毁对象时，应使用 @see std_deque_emplace_destroy() 接口。
 * 
 * @param [out] xdeq_this : 创建 xstd_deque_t 对象使用的缓存。
 * @param [in ] xdeq_ctxt : 队列 所存储的节点元素上下文描述信息。
 * 
 * @return xdeq_this_t : 返回所创建的 xstd_deque_t 对象指针。
 */
xdeq_this_t std_deque_emplace_create(
                    xdeq_this_t xdeq_this,
                    xdeq_ctxt_t xdeq_ctxt)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(XDEQ_NULL != xdeq_ctxt);
    XASSERT(0 != xdeq_ctxt->xstd_etype);
    XASSERT(0 != xdeq_ctxt->xstd_esize);

    //======================================

    XDEQ_ECTXT_UPDATE(xdeq_this, xdeq_ctxt);

    xdeq_this->xchk_size = deque_calc_chksize(xdeq_this);
    xdeq_this->xmax_size = deque_calc_maxsize(xdeq_this);
    xdeq_this->xdeq_size = 0;
    xdeq_this->xchk_rptr = XDEQ_NULL;
    xdeq_this->xmap_bpos = 0;
    xdeq_this->xmap_maxv = 0;
    xdeq_this->xmap_size = 0;
    xdeq_this->xmap_pptr = XDEQ_NULL;

    //======================================

    return xdeq_this;
}

/**********************************************************/
/**
 * @brief 
 * 销毁 xstd_deque_t 对象，
 * 其由 @see std_deque_emplace_create() 接口所创建。
 */
xdeq_void_t std_deque_emplace_destroy(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    std_deque_clear(xdeq_this);
}

/**********************************************************/
/**
 * @brief 返回 xstd_deque_t 对象的 上下文信息。
 */
xdeq_ctxt_t std_deque_ctxt(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    return XDEQ_ECTXT(xdeq_this);
}

/**********************************************************/
/**
 * @brief 返回 xstd_deque_t 对象的 类型标识。
 */
xdeq_size_t std_deque_etype(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    return XDEQ_ETYPE(xdeq_this);
}

/**********************************************************/
/**
 * @brief 返回 xstd_deque_t 对象当前的节点数量。
 */
xdeq_size_t std_deque_size(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    return xdeq_this->xdeq_size;
}

/**********************************************************/
/**
 * @brief 判断 xstd_deque_t 对象是否为空。
 */
xdeq_bool_t std_deque_empty(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    return (0 == xdeq_this->xdeq_size);
}

/**********************************************************/
/**
 * @brief 返回 xstd_deque_t 对象可容纳最大的节点数量。
 */
xdeq_size_t std_deque_maxsize(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    return XDEQ_MAX_SIZE(xdeq_this);
}

/**********************************************************/
/**
 * @brief 
 * 调整 xstd_deque_t 对象的内部存储缓存大小，
 * 释放多余空间，以适应当前容纳的节点元素数量。
 */
xdeq_void_t std_deque_shrink(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    deque_map_reduce(xdeq_this);
    deque_cptr_recyc(xdeq_this, XDEQ_NULL);
}

/**********************************************************/
/**
 * @brief 将 多个（相同的）节点值 指派给 xstd_deque_t 对象。
 * @note  该操作会更新整个 xstd_deque_t 对象，包括节点数量。
 * 
 * @param [in,out] xdeq_this : xstd_deque_t 对象。
 * @param [in    ] xdeq_size : 指派的节点数量。
 * @param [in    ] xdeq_elem : 指派的节点值。
 */
xdeq_void_t std_deque_assign(
                xdeq_this_t xdeq_this,
                xdeq_size_t xdeq_size,
                xdeq_elem_t xdeq_elem)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(xdeq_size <= XDEQ_MAX_SIZE(xdeq_this));
    XASSERT((0 == xdeq_size) || (XDEQ_NULL != xdeq_elem));

    xdeq_size_t xst_count = 0;

    if (xdeq_size > xdeq_this->xdeq_size)
    {
        deque_range_conver(
            xdeq_this,
            xdeq_elem,
            XDEQ_BEGIN(xdeq_this),
            XDEQ_END(xdeq_this));

        xst_count = xdeq_size - xdeq_this->xdeq_size;
        while (xst_count-- > 0)
        {
            std_deque_push_back(xdeq_this, xdeq_elem);
        }
    }
    else if (xdeq_size < xdeq_this->xdeq_size)
    {
        deque_range_conver(
            xdeq_this,
            xdeq_elem,
            XDEQ_BEGIN(xdeq_this),
            XDEQ_BEGIN(xdeq_this) + xdeq_size);

        xst_count = xdeq_this->xdeq_size - xdeq_size;
        while (xst_count-- > 0)
        {
            std_deque_pop_back(xdeq_this);
        }
    }
    else
    {
        deque_range_conver(
            xdeq_this,
            xdeq_elem,
            XDEQ_BEGIN(xdeq_this),
            XDEQ_END(xdeq_this));
    }
}

/**********************************************************/
/**
 * @brief 使用指定元素值填充 xstd_deque_t 对象指定区域的节点元素。
 * 
 * @param [in,out] xdeq_this   : xstd_deque_t 对象。
 * @param [in    ] xiter_first : 填充操作的区域起始节点位置。
 * @param [in    ] xiter_last  : 填充操作的区域结束节点位置。
 * @param [in    ] xdeq_elem   : 填充操作所使用的。
 * 
 * @return xdeq_iter_t : 返回 xiter_last 对应的节点迭代器。
 */
xdeq_iter_t std_deque_fill(
                xdeq_this_t xdeq_this,
                xdeq_iter_t xiter_first,
                xdeq_iter_t xiter_last,
                xdeq_elem_t xdeq_elem)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(deque_iter_inscope(xdeq_this, xiter_first, xiter_last));
    XASSERT(XDEQ_NULL != xdeq_elem);

    xdeq_opos_t xdeq_bpos = XDEQ_ITER_CAST(xdeq_opos_t, xiter_first);
    xdeq_opos_t xdeq_epos = XDEQ_ITER_CAST(xdeq_opos_t, xiter_last );

    deque_range_conver(xdeq_this, xdeq_elem, xdeq_bpos, xdeq_epos);

    return XDEQ_ITER_CAST(xdeq_iter_t, xdeq_epos);
}

/**********************************************************/
/**
 * @brief 返回 xdeq_this 对象指定索引位置上的 元素。
 * 
 * @param [in ] xdeq_this : xdeq_this 对象。
 * @param [in ] xdeq_opos : 索引位置（相对于 0 的偏移量）。
 * 
 * @return xdeq_elem_t : 所存储的元素对象。
 */
xdeq_elem_t std_deque_at(xdeq_this_t xdeq_this, xdeq_size_t xdeq_opos)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(xdeq_opos < xdeq_this->xdeq_size);
    return XDEQ_ELEM(xdeq_this, xdeq_opos);
}

/**********************************************************/
/**
 * @brief 返回 xstd_deque_t 对象的前端节点值。
 */
xdeq_elem_t std_deque_front(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(xdeq_this->xdeq_size > 0);
    return XDEQ_FRONT(xdeq_this);
}

/**********************************************************/
/**
 * @brief 返回 xstd_deque_t 对象的后端节点值。
 */
xdeq_elem_t std_deque_back(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(xdeq_this->xdeq_size > 0);
    return XDEQ_BACK(xdeq_this);
}

/**********************************************************/
/**
 * @brief 清除 xstd_deque_t 对象中的所有节点。
 */
xdeq_void_t std_deque_clear(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);

    while (xdeq_this->xdeq_size > 0)
    {
        std_deque_pop_back(xdeq_this);
    }

    std_deque_shrink(xdeq_this);
}

/**********************************************************/
/**
 * @brief 
 * 在 xstd_deque_t 对象指定位置上插入元素。
 * @note 
 * 该操作有可能导致 xstd_deque_t 对象扩容，引起外部操作的迭代器无效。
 * 
 * @param [in,out] xdeq_this : xstd_deque_t 对象。
 * @param [in    ] xiter_pos : 插入节点的位置。
 * @param [in    ] xdeq_elem : 节点所存储的元素。
 * 
 * @return xdeq_iter_t : 插入后的节点对应的迭代器位置。
 */
xdeq_iter_t std_deque_insert(
                xdeq_this_t xdeq_this,
                xdeq_iter_t xiter_pos,
                xdeq_elem_t xdeq_elem)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(deque_iter_valid(xdeq_this, xiter_pos));
    XASSERT(XDEQ_NULL != xdeq_elem);
    XASSERT(xdeq_this->xdeq_size < XDEQ_MAX_SIZE(xdeq_this));

    //======================================

    XDEQ_INSERT_BEGIN(XDEQ_ITER_CAST(xdeq_opos_t, xiter_pos), 1);
    XDEQ_INSERT_ALFORM(XDEQ_ITER_CAST(xdeq_opos_t, xiter_pos), xdeq_elem);
    return XDEQ_INSERT_END(XDEQ_ITER_CAST(xdeq_opos_t, xiter_pos));

    //======================================
}

/**********************************************************/
/**
 * @brief 
 * 以右值 move 操作元素拷贝的方式，
 * 在 xstd_deque_t 对象指定位置上安放新元素。
 * @note 
 * 该操作有可能导致 xstd_deque_t 对象扩容，
 * 引起外部操作的迭代器无效。
 * 
 * @param [in,out] xdeq_this : xstd_deque_t 对象。
 * @param [in    ] xiter_pos : 插入节点的位置。
 * @param [in    ] xdeq_elem : 节点所存储的元素。
 * 
 * @return xdeq_iter_t : 安放后的节点对应的迭代器位置。
 */
xdeq_iter_t std_deque_emplace(
                xdeq_this_t xdeq_this,
                xdeq_iter_t xiter_pos,
                xdeq_elem_t xdeq_elem)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(deque_iter_valid(xdeq_this, xiter_pos));
    XASSERT(XDEQ_NULL != xdeq_elem);
    XASSERT(xdeq_this->xdeq_size < XDEQ_MAX_SIZE(xdeq_this));

    //======================================

    XDEQ_INSERT_BEGIN(XDEQ_ITER_CAST(xdeq_opos_t, xiter_pos), 1);
    XDEQ_INSERT_ALMOVE(XDEQ_ITER_CAST(xdeq_opos_t, xiter_pos), xdeq_elem);
    return XDEQ_INSERT_END(XDEQ_ITER_CAST(xdeq_opos_t, xiter_pos));

    //======================================
}

/**********************************************************/
/**
 * @brief 在 xstd_deque_t 对象指定位置上插入多个同值元素。
 * @note 
 * 该操作有可能导致 xstd_deque_t 对象扩容，引起外部操作的迭代器无效。
 * 
 * @param [in,out] xdeq_this : xstd_deque_t 对象。
 * @param [in    ] xiter_pos : 插入的位置。
 * @param [in    ] xst_count : 插入的节点元素数量。
 * @param [in    ] xdeq_elem : 插入的同值元素。
 * 
 * @return xdeq_iter_t : 插入后对应的起始节点迭代器位置。
 */
xdeq_iter_t std_deque_insert_n(
                xdeq_this_t xdeq_this,
                xdeq_iter_t xiter_pos,
                xdeq_size_t xst_count,
                xdeq_elem_t xdeq_elem)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(deque_iter_valid(xdeq_this, xiter_pos));
    XASSERT(XDEQ_NULL != xdeq_elem);
    XASSERT(xst_count <= (XDEQ_MAX_SIZE(xdeq_this) - xdeq_this->xdeq_size));

    //======================================

    XDEQ_INSERT_BEGIN(XDEQ_ITER_CAST(xdeq_opos_t, xiter_pos), xst_count);
    XDEQ_INSERT_FILL(XDEQ_ITER_CAST(xdeq_opos_t, xiter_pos), xdeq_elem);
    return XDEQ_INSERT_END(XDEQ_ITER_CAST(xdeq_opos_t, xiter_pos));

    //======================================
}

/**********************************************************/
/**
 * @brief 从 xstd_deque_t 对象中删除指定的节点。
 * 
 * @param [in,out] xdeq_this : xstd_deque_t 对象。
 * @param [in    ] xiter_pos : 删除节点的所在位置。
 * 
 * @return xdeq_iter_t : 返回 xiter_pos 的后继节点迭代器。
 */
xdeq_iter_t std_deque_erase(xdeq_this_t xdeq_this, xdeq_iter_t xiter_pos)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(deque_iter_ref(xdeq_this, xiter_pos));

    xdeq_opos_t xdeq_opos = XDEQ_ITER_CAST(xdeq_opos_t, xiter_pos);

    XDEQ_ALDEST(xdeq_this, XDEQ_ELEM(xdeq_this, xdeq_opos));

    if (xdeq_opos <= (xdeq_this->xdeq_size / 2))
    {
        deque_head_rshift(xdeq_this, xdeq_opos, 1);
    }
    else
    {
        deque_tail_lshift(xdeq_this, xdeq_opos + 1, 1);
    }

    return XDEQ_ITER_CAST(xdeq_iter_t, xdeq_opos);
}

/**********************************************************/
/**
 * @brief 
 * 从 xstd_deque_t 对象中删除 [ xiter_first, xiter_last ) 区域上的各个元素。
 * 
 * @param [in,out] xdeq_this   : xstd_deque_t 对象。
 * @param [in    ] xiter_first : 迭代区域的起始位置。
 * @param [in    ] xiter_last  : 迭代区域的结束位置。
 * 
 * @return xdeq_iter_t : 返回 xiter_last 迭代器对应的节点。
 */
xdeq_iter_t std_deque_erase_range(
                xdeq_this_t xdeq_this,
                xdeq_iter_t xiter_first,
                xdeq_iter_t xiter_last)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(deque_iter_inscope(xdeq_this, xiter_first, xiter_last));

    xdeq_opos_t xdeq_bpos = XDEQ_ITER_CAST(xdeq_opos_t, xiter_first);
    xdeq_opos_t xdeq_epos = XDEQ_ITER_CAST(xdeq_opos_t, xiter_last);
    xdeq_size_t xdeq_size = xdeq_epos - xdeq_bpos;

    deque_range_erase(xdeq_this, xdeq_bpos, xdeq_epos);

    if ((xdeq_bpos - XDEQ_BEGIN(xdeq_this)) <=
        (XDEQ_END(xdeq_this) - xdeq_epos))
    {
        deque_head_rshift(xdeq_this, xdeq_bpos, xdeq_size);
    }
    else
    {
        deque_tail_lshift(xdeq_this, xdeq_epos, xdeq_size);
    }

    return XDEQ_ITER_CAST(xdeq_iter_t, xdeq_bpos);
}

/**********************************************************/
/**
 * @brief
 * 调整 xstd_deque_t 对象中的节点数量到 指定值。
 * 若 指定值 多于原有的节点数量，则使用 指定节点元素 补充多出的节点。
 * 
 * @param [in,out] xdeq_this : xstd_deque_t 对象。
 * @param [in    ] xdeq_size : 所要调整到的节点数量。
 * @param [in    ] xdeq_elem : 补充操作时使用的节点元素。
 */
xdeq_void_t std_deque_resize(
                xdeq_this_t xdeq_this,
                xdeq_size_t xdeq_size,
                xdeq_elem_t xdeq_elem)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(xdeq_size <= XDEQ_MAX_SIZE(xdeq_this));

    xdeq_size_t xst_count = 0;

    if (xdeq_size == xdeq_this->xdeq_size)
    {
        return;
    }

    if (xdeq_size > xdeq_this->xdeq_size)
    {
        XASSERT(XDEQ_NULL != xdeq_elem);

        xst_count = xdeq_size - xdeq_this->xdeq_size;
        while (xst_count-- > 0)
        {
            std_deque_push_back(xdeq_this, xdeq_elem);
        }
    }
    else
    {
        xst_count = xdeq_this->xdeq_size - xdeq_size;
        while (xst_count-- > 0)
        {
            std_deque_pop_back(xdeq_this);
        }
    }
}

/**********************************************************/
/**
 * @brief 向 xstd_deque_t 对象前端新增一个节点。
 */
xdeq_void_t std_deque_push_front(
                xdeq_this_t xdeq_this,
                xdeq_elem_t xdeq_elem)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(XDEQ_NULL != xdeq_elem);
    XASSERT(xdeq_this->xdeq_size < XDEQ_MAX_SIZE(xdeq_this));

    //======================================

    XDEQ_PUSH_FRONT_BEGIN;
    XDEQ_PUSH_ALFROM(xdeq_elem);
    XDEQ_PUSH_FRONT_END;

    //======================================
}

/**********************************************************/
/**
 * @brief 向 xstd_deque_t 对象前端新增一个节点，元素以 右值move 方式进行存储。
 */
xdeq_void_t std_deque_push_mfront(
                xdeq_this_t xdeq_this,
                xdeq_elem_t xdeq_elem)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(XDEQ_NULL != xdeq_elem);
    XASSERT(xdeq_this->xdeq_size < XDEQ_MAX_SIZE(xdeq_this));

    //======================================

    XDEQ_PUSH_FRONT_BEGIN;
    XDEQ_PUSH_ALMOVE(xdeq_elem);
    XDEQ_PUSH_FRONT_END;

    //======================================
}

/**********************************************************/
/**
 * @brief 将 xstd_deque_t 对象的前端节点弹出（删除）。
 */
xdeq_void_t std_deque_pop_front(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(xdeq_this->xdeq_size > 0);

    xdeq_cpos_t xmap_cpos = XDEQ_CPOS(xdeq_this, XDEQ_BEGIN(xdeq_this));
    xdeq_npos_t xmap_npos = XDEQ_NPOS(xdeq_this, XDEQ_BEGIN(xdeq_this));

    XDEQ_ALDEST(xdeq_this, XDEQ_NPTR(xdeq_this, xmap_cpos, xmap_npos));

    if ((xdeq_this->xchk_size - 1) == xmap_npos)
    {
        deque_cptr_recyc(xdeq_this, XDEQ_CPTR(xdeq_this, xmap_cpos));
        XDEQ_CPTR(xdeq_this, xmap_cpos) = XDEQ_NULL;
    }

    if (0 == --xdeq_this->xdeq_size)
        xdeq_this->xmap_bpos = 0;
    else
        xdeq_this->xmap_bpos = XDEQ_VPOS(xdeq_this, XDEQ_BEGIN(xdeq_this) + 1);
}

/**********************************************************/
/**
 * @brief 向 xstd_deque_t 对象后端新增一个节点。
 */
xdeq_void_t std_deque_push_back(
                xdeq_this_t xdeq_this,
                xdeq_elem_t xdeq_elem)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(XDEQ_NULL != xdeq_elem);
    XASSERT(xdeq_this->xdeq_size < XDEQ_MAX_SIZE(xdeq_this));

    //======================================

    XDEQ_PUSH_BACK_BEGIN;
    XDEQ_PUSH_ALFROM(xdeq_elem);
    XDEQ_PUSH_BACK_END;

    //======================================
}

/**********************************************************/
/**
 * @brief 向 xstd_deque_t 对象后端新增一个节点，元素以 右值move 方式进行存储。
 */
xdeq_void_t std_deque_push_mback(
                xdeq_this_t xdeq_this,
                xdeq_elem_t xdeq_elem)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(XDEQ_NULL != xdeq_elem);
    XASSERT(xdeq_this->xdeq_size < XDEQ_MAX_SIZE(xdeq_this));

    //======================================

    XDEQ_PUSH_BACK_BEGIN;
    XDEQ_PUSH_ALMOVE(xdeq_elem);
    XDEQ_PUSH_BACK_END;

    //======================================
}

/**********************************************************/
/**
 * @brief 将 xstd_deque_t 对象的后端节点弹出（删除）。
 */
xdeq_void_t std_deque_pop_back(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(xdeq_this->xdeq_size > 0);

    xdeq_cpos_t xmap_cpos = XDEQ_CPOS(xdeq_this, XDEQ_RBEGIN(xdeq_this));
    xdeq_npos_t xmap_npos = XDEQ_NPOS(xdeq_this, XDEQ_RBEGIN(xdeq_this));

    XDEQ_ALDEST(xdeq_this, XDEQ_NPTR(xdeq_this, xmap_cpos, xmap_npos));

    if (0 == xmap_npos)
    {
        deque_cptr_recyc(xdeq_this, XDEQ_CPTR(xdeq_this, xmap_cpos));
        XDEQ_CPTR(xdeq_this, xmap_cpos) = XDEQ_NULL;
    }

    if (0 == --xdeq_this->xdeq_size)
        xdeq_this->xmap_bpos = 0;
}

/**********************************************************/
/**
 * @brief 返回 xstd_deque_t 对象指定索引位置对应的迭代器。
 * 
 * @param [in ] xdeq_this : xstd_deque_t 对象。
 * @param [in ] xdeq_vpos : 索引位置。
 * 
 * @return xdeq_iter_t : 索引位置对应的迭代器。
 */
xdeq_iter_t std_deque_iter(xdeq_this_t xdeq_this, xdeq_size_t xdeq_vpos)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(xdeq_vpos <= xdeq_this->xdeq_size);
    return XDEQ_ITER_CAST(xdeq_iter_t, xdeq_vpos);
}

/**********************************************************/
/**
 * @brief 返回 xstd_deque_t 对象的起始节点 迭代器 位置。
 */
xdeq_iter_t std_deque_begin(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    return XDEQ_ITER_CAST(xdeq_iter_t, XDEQ_BEGIN(xdeq_this));
}

/**********************************************************/
/**
 * @brief 返回 xstd_deque_t 对象的结束节点 迭代器 位置。
 */
xdeq_iter_t std_deque_end(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    return XDEQ_ITER_CAST(xdeq_iter_t, XDEQ_END(xdeq_this));
}

/**********************************************************/
/**
 * @brief 对 xstd_deque_t 对象的迭代器进行前移一个节点位置。
 */
xdeq_iter_t std_deque_next(xdeq_this_t xdeq_this, xdeq_iter_t xiter_trav)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(deque_iter_ref(xdeq_this, xiter_trav));
    return XDEQ_ITER_CAST(xdeq_iter_t, XDEQ_ITER_CAST(xdeq_opos_t, xiter_trav) + 1);
}

/**********************************************************/
/**
 * @brief 返回 xstd_deque_t 对象的反向起始节点 迭代器 位置。
 */
xdeq_iter_t std_deque_rbegin(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    return XDEQ_ITER_CAST(xdeq_iter_t, XDEQ_RBEGIN(xdeq_this));
}

/**********************************************************/
/**
 * @brief 返回 xstd_deque_t 对象的反向结束节点 迭代器 位置。
 */
xdeq_iter_t std_deque_rend(xdeq_this_t xdeq_this)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    return XDEQ_ITER_CAST(xdeq_iter_t, XDEQ_REND(xdeq_this));
}

/**********************************************************/
/**
 * @brief 对 xstd_deque_t 对象的迭代器反向进行前移一个节点位置。
 */
xdeq_iter_t std_deque_rnext(xdeq_this_t xdeq_this, xdeq_iter_t xiter_trav)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(deque_iter_ref(xdeq_this, xiter_trav));
    return XDEQ_ITER_CAST(xdeq_iter_t, XDEQ_ITER_CAST(xdeq_opos_t, xiter_trav) - 1);
}

/**********************************************************/
/**
 * @brief 返回 xstd_deque_t 对象的迭代器对应存储的元素值。
 */
xdeq_elem_t std_deque_elem(xdeq_this_t xdeq_this, xdeq_iter_t xiter_trav)
{
    XASSERT(XDEQ_NULL != xdeq_this);
    XASSERT(deque_iter_ref(xdeq_this, xiter_trav));
    return XDEQ_ELEM(xdeq_this, XDEQ_ITER_CAST(xdeq_opos_t, xiter_trav));
}

////////////////////////////////////////////////////////////////////////////////

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif // __GNUC__

////////////////////////////////////////////////////////////////////////////////

